<?php
class Delivery_Model_Mapper_Productos
	extends Delivery_Model_Mapper_Abstract
{
	
	public function getDbTable()
	{
		return parent::getDbTable( 'Productos' );
	}
	
	public function save ( $producto, $disactiveIfInAnyOrder = true ){
		
		$dbTable= $this->getDbTAble();
		
		if ( ! $producto->getId() ){	
			$producto->idProducto = $dbTable->insert( $producto );
		} else {							
			
			$mapper1 = Delivery_Model_Factory::mapper('ProductosPedido');
			$mapper2 = Delivery_Model_Factory::mapper('PromocionesPedido');
			//chequeo si el producto esta en algún pedido
			if ( $disactiveIfInAnyOrder && (
						$mapper1->inAnyOrder( $producto->getId() ) ||
						$mapper2->hasProduct( $producto->getId() )
					)
				){			
				
				//chequeo si el producto esta en alguna promoción
				$mapper3 = Delivery_Model_Factory::mapper('ItemsPromocion');
				$inAnyItem = $mapper3->inAnyItem( $producto->idProducto );
				
				if ( $inAnyItem ){	
					throw new Delivery_Model_Exception( Delivery_Model_Exception::PRODUCT_CANNOT_BE_MODIFIED );						
				}

				$idProductoOld = $producto->getId();
				
				$this->_disactive( $idProductoOld );
				
				$producto->idProducto = null;
				$producto->idProducto = $dbTable->insert( $producto );
				
				
				//Aca hay que ver si tiene opciones asociadas y mantenerlas
				$this->_copyOptions( $idProductoOld, $producto->idProducto);
				
				
			}else {
				$dbTable->update( $producto );	
			}	
		}			
		
		return $this;
	}
	
	/**
	 * @param object $producto
	 * @return boolen
	 */
	public function delete( $producto ){
	
		$dbTable= $this->getDbTAble();
		
		//chequeo si el producto esta en alguna promoción
		$mapper1 = Delivery_Model_Factory::mapper('ItemsPromocion');
		$inAnyItem = $mapper1->inAnyItem( $producto->idProducto );
		
		if ( $inAnyItem ){	
			throw new Delivery_Model_Exception( Delivery_Model_Exception::PRODUCT_CANNOT_BE_DELETED );						
		}
		
		$mapper2 = Delivery_Model_Factory::mapper('ProductosPedido');
		$mapper3 = Delivery_Model_Factory::mapper('PromocionesPedido');
		
		//chequeo si el producto esta en algún pedido
		if ( $mapper2->inAnyOrder( $producto->getId() ) ||
			 $mapper3->hasProduct( $producto->getId() ) ){			
			
			$producto->activo = 0;
			return $dbTable->update(  $producto  );
			
		} else {
			$this->logDeleted( $producto );
		}
		
		return $dbTable->delete( $producto );
	}
	
	
	/**
	 * @param int $idProducto
	 * @param int $idNegocio
	 * @return object Delivery_Model_Producto
	 */
	public function getById( $idProducto , $idNegocio = null  )
	{
		if ( $this->getIdentityMap()->isRegistered( 'Delivery_Model_Producto', $idProducto )){
			return $this->getIdentityMap()->get( 'Delivery_Model_Producto', $idProducto );
		}
		
		$dbTable= $this->getDbTAble();
		$row	= $dbTable->getById( $idProducto, $idNegocio );
	
		if( empty($row) ){
			throw new Delivery_Model_Exception( Delivery_Model_Exception::PRODUCT_NOT_FOUND );
		}
		
		return $this->_fetch( $row );
	}
	
	public function getByIds( $ids )
	{
		$dbTable= $this->getDbTAble();
		
		return $this->_fetchCollection(
			'Productos',
			$dbTable->getByIds( $ids )
		);
	}
	
	public function getByNegocio( $idNegocio )
	{
		$dbTable= $this->getDbTAble();
		
		return $this->_fetchCollection(
			'Productos',
			$dbTable->getByNegocio( $idNegocio )
		);
	}
	
	/**
	 * @param array
	 * @return array objetos producto
	 */
	public function getByParams( $params, $offset = null, $limit = null, $order = null ){
		
		$dbTable= $this->getDbTAble();
		
		return $this->_fetchCollection(
			'Productos',
			$dbTable->getByParams($params, $offset, $limit, $order)
		);
	}
	
	public function countByParams( $params ){
		return $this->getDbTAble()->countByParams($params);
	}
	
	
	public function loadCategoria( $productos )
	{
		$mapper = Delivery_Model_Factory::mapper('Categorias');
		
		if (  $productos instanceof Delivery_Model_Collection_Productos || $productos instanceof Delivery_Model_Collection_ProductosPedidos ){

			if (count( $productos ) < 1){
				return;
			}
			
			$categorias = $mapper->getByIds( $productos->getKeyValues( 'idCategoria', true ) );
			
			foreach ( $productos as $producto){
				$producto->setCategoria(
					$categorias->offsetGet( $producto->idCategoria )
				);
			}
		}
	 	elseif ( $productos instanceof Delivery_Model_Producto){
			
	 		$productos->setCategoria(
	 			$mapper->getById( $productos->idCategoria )
	 		);
		}
	}
	
	public function loadNegocio( $productos )
	{
		$mapper = Delivery_Model_Factory::mapper('Negocios');
		
		if ( $productos instanceof Delivery_Model_Collection_Productos || $productos instanceof Delivery_Model_Collection_ProductosPedidos ){

			if (count( $productos ) < 1){
				return;
			}
			
			$negocios = $mapper->getByIds( $productos->getKeyValues( 'idNegocio', true ) );
			$productos->setNegocio( $negocios );
			
			return $negocios;
			
		}
	 	elseif ( $productos instanceof Delivery_Model_Producto){
			
	 	    $negocio = $mapper->getById( $producto->idNegocio );
	 	    
	 		$productos->setNegocio($negocio);
	 		
	 		return $negocio;
		}
	}
	
	public function loadOpciones( $productos )
	{
		$mapper1 = Delivery_Model_Factory::mapper('OpcionesFamiliasProductos');
		$mapper2 = Delivery_Model_Factory::mapper('Opciones');
		
		if ( $productos instanceof Delivery_Model_Collection_Productos && count($productos)){
		
			$familias = $mapper1->getByProducto( $productos->getIds() );
			
		    if( !count($familias)){
	 			return;
	 		}
			
			$opciones = $mapper2->getByOpcionFamilia( $familias->getKeyValues('idOpcionFamilia', true) );
			
		    foreach ( $opciones as $opcion){
				
				$opcion->setFamilia( current($familias->getByKey('idOpcionFamilia', $opcion->idOpcionFamilia)) );
			}
			
			foreach ( $familias as $familia){
				
			    $productos2 = $productos->getByKey('idProducto', $familia->idProducto);
			    
			    
			    foreach ( $productos2 as $producto2){
			    
			        $productoOpciones =  $producto2->getOpciones();
			        
    			    if( !is_null($productoOpciones)){
    			    
    			        $opciones2 = $opciones->getByKey('idOpcionFamilia', $familia->idOpcionFamilia);
    			        
    			        foreach ( $opciones2 as $opcion2){
    			            $productoOpciones->append($opcion2);
    			        }
    			    
    			    } else {
    			        $producto2->setOpciones(
    			            $opciones->getByKey('idOpcionFamilia', $familia->idOpcionFamilia)
    			        );
    			    }
			    }
			}
		}
		
	 	elseif ( $productos instanceof Delivery_Model_Producto){
			
	 		$familias = $mapper1->getByProducto( $productos->getId() );
	 		
	 		
	 		if( !count($familias)){
	 			return;
	 		}
	 		
			$opciones = $mapper2->getByOpcionFamilia( $familias->getKeyValues('idOpcionFamilia', true) );
	 		
	 		foreach ( $opciones as $opcion){
				
				$opcion->setFamilia( current($familias->getByKey('idOpcionFamilia', $opcion->idOpcionFamilia)) );
			}
	 		
	 		$productos->setOpciones( $opciones );
		}
		
		
	}
	
	public function copiar( $idNegocioFrom, $idCategoriaFrom, $idNegocioTo, $idCategoriaTo, 
	                        $copiarStock, $copiarDescripcion, $copiarCodigo, $copiarOpciones)
	{
	    $db = Zend_Registry::get('db');								
		$db->beginTransaction();
	    
	    try {
	    
	        $params = array(
    		    'idNegocio'	    => $idNegocioFrom
    		);
    		
    		if( $idCategoriaFrom && $idCategoriaTo ){
    		    $params['idCategoria'] = $idCategoriaFrom;
    		}
	        
	        
    	    $productos = $this->getByParams( $params ); 
    		
    	    $this->loadOpciones( $productos );
    	    
    	    $opcionesFamiliasParaCopiar = Delivery_Model_Factory::collection( 'OpcionesFamiliasProductos' );
    	    $opcionesParaCopiar = Delivery_Model_Factory::collection( 'Opciones' );
    	    
    	    
    	    $familiasOldIds = array();
    		$opcionesOldIds = array();
    		$productosOldIds = array();
		
    		foreach ($productos as $producto){
    				
    		    $productoNuevo = new Delivery_Model_Producto;
    		    $productoNuevo->nombre = $producto->nombre;
    		    $productoNuevo->precio = $producto->precio;
    		    $productoNuevo->descripcion = '';
    		    $productoNuevo->cantidadVendida = 0;
    		    $productoNuevo->cantidadDisponible = 2499;
    		    $productoNuevo->idNegocio = $idNegocioTo;
    		    
    		    if( $idCategoriaFrom && $idCategoriaTo && $idCategoriaFrom != $idCategoriaTo){
    		        $productoNuevo->idCategoria = $idCategoriaTo;
    		    }else{
    		        $productoNuevo->idCategoria = $producto->idCategoria;
    		    }
    		    
    		    if( $copiarStock ){
    		        $productoNuevo->cantidadDisponible = $producto->cantidadDisponible;
    		    }
    		    
    		    if( $copiarDescripcion ){
    		        $productoNuevo->descripcion = $producto->descripcion;
    		    }
    		    
    		    if( $copiarCodigo ){
    		        $productoNuevo->codigo = $producto->codigo;
    		    }
    		    $this->save( $productoNuevo );
    		    
    		    $productosOldIds[$producto->getId()] = $productoNuevo->getId();
    		    
    		    if( $copiarOpciones && $producto->getOpciones()){
    		        
    		        if ($productoNuevo->idNegocio == $producto->idNegocio ){
    		            $this->_copyOptions( $producto->getId(), $productoNuevo->getId() );
    		        } else {
    		        
    			        $opciones = $producto->getOpciones();
    			        				        
    			        foreach ($opciones as $opcion){
    			            
    			            $opcionesParaCopiar->append( $opcion );
    			            $opcionesFamiliasParaCopiar->append( $opcion->getFamilia() );
    			        }
    		        }
    		    }
    		}
		
    		if(count($opcionesParaCopiar)){
    		
    		    $mapperF = Delivery_Model_Factory::mapper( 'OpcionesFamilias' );
    		    		    		    
    		    $opcionesFamilias = $mapperF->getByIds($opcionesFamiliasParaCopiar->getKeyValues('idOpcionFamilia', true, true));
    		    
    		    foreach ($opcionesFamilias as $idOpcionFamiliaOld => $familia){
    		        $familia->idOpcionFamilia = null;
    		        $familia->idNegocio = $idNegocioTo;
    		    
    		        $mapperF->save( $familia );
    		        
    		        $familiasOldIds[$idOpcionFamiliaOld] = $familia->getId();
    		        
    		    }
    		    
    		    $mapperO = Delivery_Model_Factory::mapper( 'Opciones' );
    		    
    		    foreach ($opcionesParaCopiar as $idOpcionOld => $opcion){
    		    
    		        $opcion->idOpcion = null;
    		        $opcion->idNegocio = $idNegocioTo;
    		        $opcion->idOpcionFamilia = $familiasOldIds[$opcion->idOpcionFamilia];
    		        
    		        $mapperO->save( $opcion );
    		        
    		        $opcionesOldIds[$idOpcionOld] = $opcion->getId();
    		    }
    		    
    		    $mapperOF = Delivery_Model_Factory::mapper( 'OpcionesFamiliasProductos' );
    		    
    		    foreach ($opcionesFamiliasParaCopiar as $idOpcionFamiliaProductoOld => $opcionFamiliaProducto){
    
    		        $opcionFamiliaProducto->idOpcionFamiliaProducto = null;
    		        $opcionFamiliaProducto->idProducto = $productosOldIds[$opcionFamiliaProducto->idProducto];
    		        $opcionFamiliaProducto->idOpcionFamilia = $familiasOldIds[$opcionFamiliaProducto->idOpcionFamilia];
    		        
    		        $mapperOF->save( $opcionFamiliaProducto );
    		    }
    		}
    		
    		$db->commit();
		
	    } catch (Delivery_Model_Exception $e) {
			$db->rollBack();
			throw $e;
		}catch (Zend_Exception $e) {
			$db->rollBack();
			throw $e;
		}
		
	}
	
	/**
	 * @param array
	 * @return object Delivery_Model_Producto
	 */
	protected function _fetch( $row )
	{
		$producto = new Delivery_Model_Producto( $row );
		
		$this->getIdentityMap()->set( $producto, $producto->getId() );
		
		return $producto;
	}
	
	/**
	 * Si un producto tiene opciones relacionadas, se actualiza
	 * 
	 * @param int idProductoOld
	 * @param int idProducto
	 * @return void
	 */
	protected function _copyOptions( $idProductoOld, $idProducto)
	{
	    $mapper = Delivery_Model_Factory::mapper('OpcionesFamiliasProductos');
	    $opcionesFamiliasProductos = $mapper->getByProducto( $idProductoOld );
	    
	    if( count($opcionesFamiliasProductos)){
	         foreach( $opcionesFamiliasProductos as $opcionFamiliaProducto){
	             $opcionFamiliaProducto->idOpcionFamiliaProducto = null;
	             $opcionFamiliaProducto->idProducto = $idProducto;
	             $mapper->save( $opcionFamiliaProducto );
	         }
	    }
	    
	}
	
	/**
	 * Si un producto esta en un pedido y es modificado
	 * guardo una copia exacta del producto pedido
	 * 
	 * @param int idProducto
	 * @return void
	 */
	protected function _disactive( $idProducto)
	{
	    $producto = $this->getById( $idProducto );
	    $producto->activo = 0;
	    $this->getDbTAble()->update(  $producto  );
	}
	
}